//
//  XMPPManager.m
//  EWork
//
//  Created by administrator on 14-12-2.
//  Copyright (c) 2014年 gaobo. All rights reserved.
//

#import "XMPPManager.h"
#import "GCDAsyncSocket.h"
#import "XMPP.h"
#import "XMPPReconnect.h"
#import "DDLog.h"
#import "DDTTYLogger.h"
#import "XMPPRoster.h"
#import "XMPPMessage.h"
#import "TURNSocket.h"
#import "MessageObject.h"

#if DEBUG
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#else
static const int ddLogLevel = LOG_LEVEL_INFO;
#endif

#define DOCUMENT_PATH NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]
#define CACHES_PATH NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]

@implementation XMPPManager

+(XMPPManager*)sharedInstance{
    static dispatch_once_t onceToken;
    XMPPManager *sharedManager=[[XMPPManager alloc]init];
    dispatch_once(&onceToken, ^{
        [DDLog addLogger:[DDTTYLogger sharedInstance]];
        [[NSUserDefaults standardUserDefaults]setObject:[[NSUserDefaults standardUserDefaults]objectForKey:kMY_USER_ID] forKey:kXMPPmyJID];
        [[NSUserDefaults standardUserDefaults]setObject:[[NSUserDefaults standardUserDefaults]objectForKey:kMY_USER_PASSWORD] forKey:kXMPPmyPassword];
        [[NSUserDefaults standardUserDefaults]synchronize];
        [sharedManager setupStream];
    });
    return sharedManager;
}

- (NSURL *)applicationDocumentsDirectory{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

- (void)saveContext{
    NSError *error = nil;
    if(self.managedObjectContext != nil){
        if([self.managedObjectContext hasChanges] && ![self.managedObjectContext save:&error]){
            NSLog(@"save occured error:%@,%@",error,[error userInfo]);
            abort();
        }
    }
}

- (void)sendMessage:(XMPPMessage *)aMessage
{
    [xmppStream sendElement:aMessage];
    NSString *body = [[aMessage elementForName:@"body"] stringValue];
    NSString *meesageTo = [[aMessage to]bare];
    NSArray *strs=[meesageTo componentsSeparatedByString:@"@"];
    
    //创建message对象
     MessageObject *msg=[[MessageObject alloc]init];
    [msg setMessageDate:[NSDate date]];
    [msg setMessageFrom:[[NSUserDefaults standardUserDefaults]objectForKey:kMY_USER_ID]];
    
    [msg setMessageTo:strs[0]];
    //判断多媒体消息
    
    NSDictionary *messageDic=[body JSONValue];
    NSLog(@"发送消息中:%@",[messageDic objectForKey:@"text"]);
    
    [msg setMessageType:[messageDic objectForKey:@"messageType"]];
    if (msg.messageType.intValue==kMessageTypePlain) {
        [msg setMessageContent:[messageDic objectForKey:@"text"]];
    }else{
        [msg setMessageContent:[[messageDic objectForKey:@"file"]objectForKey:@"shortPath"]];
    }
    [MessageObject save:msg];
}

#pragma mark --------配置XML流---------
- (void)setupStream
{
	NSAssert(xmppStream == nil, @"Method setupStream invoked multiple times");
	xmppStream = [[XMPPStream alloc] init];
	
#if !TARGET_IPHONE_SIMULATOR
	{
        xmppStream.enableBackgroundingOnSocket = YES;
	}
#endif
    xmppReconnect = [[XMPPReconnect alloc] init];
    xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
	xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];
	xmppRoster.autoFetchRoster = YES;
	xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;
    
	[xmppReconnect activate:xmppStream];
    [xmppRoster activate:xmppStream];
    
    [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
    allowSelfSignedCertificates = NO;
	allowSSLHostNameMismatch = YES;
    
    if (![self connect]) {
        [[[UIAlertView alloc]initWithTitle:@"服务器连接失败" message:@"ps:本demo服务器非24小时开启，若急需请QQ 109327402" delegate:self cancelButtonTitle:@"ok" otherButtonTitles: nil]show];
    }
}

- (void)teardownStream
{
	[xmppStream removeDelegate:self];
	[xmppReconnect deactivate];
	[xmppStream disconnect];
	xmppStream = nil;
	xmppReconnect = nil;
}

- (void)goOnline
{
	XMPPPresence *presence = [XMPPPresence presence]; // type="available" is implicit
	[xmppStream sendElement:presence];
}

- (void)goOffline
{
	XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
	[xmppStream sendElement:presence];
}

- (BOOL)connect
{
	if (![xmppStream isDisconnected]) {
		return YES;
	}
    
	NSString *myJID = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyJID];
	NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyPassword];
	 myJID = @"user@gmail.com/xmppframework";
	 myPassword = @"123";
	
//	if (myJID == nil || myPassword == nil) {
//		return NO;
//	}
//    
//	// ===这句注释掉 改成下面这句[xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
//    [xmppStream setMyJID:[XMPPJID jidWithUser:myJID domain:@"hcios.com" resource:@"ios"]];
//    passWord=myPassword;
//    
//	NSError *error = nil;
//	if (![xmppStream connectWithTimeout:10 error:&error]){
//		UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error connecting" message:@"See console for error details." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
//		[alertView show];
//		DDLogError(@"Error connecting: %@", error);
//		return NO;
//	}
	return YES;
}


- (void)disconnect
{
	[self goOffline];
	[xmppStream disconnect];
}

#pragma mark UIApplicationDelegate
- (void)applicationDidEnterBackground:(UIApplication *)application
{
	// Use this method to release shared resources, save user data, invalidate timers, and store
	// enough application state information to restore your application to its current state in case
	// it is terminated later.
	//
	// If your application supports background execution,
	// called instead of applicationWillTerminate: when the user quits.
	
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
    
#if TARGET_IPHONE_SIMULATOR
	DDLogError(@"The iPhone simulator does not process background network traffic. "
			   @"Inbound traffic is queued until the keepAliveTimeout:handler: fires.");
#endif
    
	if ([application respondsToSelector:@selector(setKeepAliveTimeout:handler:)])
	{
		[application setKeepAliveTimeout:600 handler:^{
			
			DDLogVerbose(@"KeepAliveHandler");
			
			// Do other keep alive stuff here.
		}];
	}
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

- (NSManagedObjectContext *)managedObjectContext_roster
{
	return [xmppRosterStorage mainThreadManagedObjectContext];
}
// Returns the URL to the application's Documents directory.
#pragma mark XMPPStream Delegate
- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

- (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
	
	if (allowSelfSignedCertificates)
	{
		[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
	}
	
	if (allowSSLHostNameMismatch)
	{
		[settings setObject:[NSNull null] forKey:(NSString *)kCFStreamSSLPeerName];
	}
	else
	{
		// Google does things incorrectly (does not conform to RFC).
		// Because so many people ask questions about this (assume xmpp framework is broken),
		// I've explicitly added code that shows how other xmpp clients "do the right thing"
		// when connecting to a google server (gmail, or google apps for domains).
		
		NSString *expectedCertName = nil;
		
		NSString *serverDomain = xmppStream.hostName;
		NSString *virtualDomain = [xmppStream.myJID domain];
		
		if ([serverDomain isEqualToString:@"talk.google.com"]){
			if ([virtualDomain isEqualToString:@"gmail.com"]){
				expectedCertName = virtualDomain;
			}else{
				expectedCertName = serverDomain;
			}
		}
		else if (serverDomain == nil){
			expectedCertName = virtualDomain;
		}else{
			expectedCertName = serverDomain;
		}
		
		if (expectedCertName){
			[settings setObject:expectedCertName forKey:(NSString *)kCFStreamSSLPeerName];
		}
	}
}

- (void)xmppStreamDidSecure:(XMPPStream *)sender
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
	
	isXmppConnected = YES;
	
	NSError *error = nil;
	
	if (![xmppStream authenticateWithPassword:passWord error:&error])
	{
		DDLogError(@"Error authenticating: %@", error);
	}
}

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
	
	[self goOnline];
    [xmppRoster fetchRoster];
}

- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
	DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [iq elementID]);
	
    NSLog(@"收到iq:%@",iq);
    
    
	return NO;
}

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
    
    NSString *body = [[message elementForName:@"body"] stringValue];
    NSString *displayName = [[message from]bare];
    
    
    [[[UIAlertView alloc]initWithTitle:@"收到新消息" message:nil delegate:self cancelButtonTitle:@"ok" otherButtonTitles: nil] show];
    
    
    //创建message对象
    MessageObject *msg=[MessageObject messageWithType:kWCMessageTypePlain];
    NSArray *strs=[displayName componentsSeparatedByString:@"@"];
    [msg setMessageDate:[NSDate date]];
    [msg setMessageFrom:strs[0]];
    [msg setMessageContent:body];
    [msg setMessageTo:[[NSUserDefaults standardUserDefaults]objectForKey:kMY_USER_ID]];
    [msg setMessageType:[NSNumber numberWithInt:kWCMessageTypePlain]];
    
    if(![UserObject haveSaveUserById:strs[0]]) {
        [self fetchUser:strs[0]];
    }
    NSDictionary *messageDic=[body JSONValue];
    [msg setMessageType:[messageDic objectForKey:@"messageType"]];
    if (msg.messageType.intValue==kWCMessageTypePlain) {
        [msg setMessageContent:[messageDic objectForKey:@"text"]];
    }else
        [msg setMessageContent:[[messageDic objectForKey:@"file"]objectForKey:@"shortPath"]];
    [MessageObject save:msg];
    if([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive)
    {
        // We are not active, so use a local notification instead
        UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.alertAction = @"Ok";
        localNotification.alertBody = [NSString stringWithFormat:@"From: %@\n\n%@",@"微信消息:",@"123"];
        
        [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
    }
}

- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
	DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [presence fromStr]);
}

- (void)xmppStream:(XMPPStream *)sender didReceiveError:(id)error
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
	DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
	
	if (!isXmppConnected)
	{
		DDLogError(@"Unable to connect to server. Check xmppStream.hostName");
	}
}

#pragma mark XMPPRosterDelegate
- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence
{
    
    XMPPJID *jid=[XMPPJID jidWithString:[presence stringValue]];
    [xmppRoster acceptPresenceSubscriptionRequestFrom:jid andAddToRoster:YES];
}

- (void)addSomeBody:(NSString *)userId
{
    [xmppRoster subscribePresenceToUser:[XMPPJID jidWithString:[NSString stringWithFormat:@"%@@hcios.com",userId]]];
}

-(void)fetchUser:(NSString*)userId
{
    UIAlertView *av=[[UIAlertView alloc]initWithTitle:@"加载中" message:@"刷新好友列表中，请稍候" delegate:self cancelButtonTitle:@"ok" otherButtonTitles: nil];
    [av show];
    
    //此API使用方式请查看www.hcios.com:8080/user/findUser.html
    ASIFormDataRequest *request=[ASIFormDataRequest requestWithURL:API_BASE_URL(@"servlet/GetUserDetailServlet")];
    
    [request setPostValue:userId forKey:@"userId"];
    [request setDelegate:self];
    [request setDidFinishSelector:@selector(requestSuccess:)];
    [request setDidFailSelector:@selector(requestError:)];
    [request startAsynchronous];
}
-(void)requestSuccess:(ASIFormDataRequest*)request
{
    NSLog(@"response:%@",request.responseString);
    SBJsonParser *paser=[[SBJsonParser alloc]init];
    NSDictionary *rootDic=[paser objectWithString:request.responseString];
    int resultCode=[[rootDic objectForKey:@"result_code"]intValue];
    if (resultCode==1) {
        NSDictionary *dic=[rootDic objectForKey:@"data"];
        UserObject *user=[UserObject userFromDictionary:dic];
        [UserObject saveNewUser:user];
    }
}


-(void)requestError:(ASIFormDataRequest*)request
{
    
}

-(void)sendFile:(NSData*)aData toJID:(XMPPJID*)aJID{
    
}
@end
